package com.my.blog.myblog.controller.admin;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.my.blog.annotation.SystemLog;
import com.my.blog.myblog.entity.Blog;
import com.my.blog.myblog.entity.Blogtype;
import com.my.blog.myblog.entity.custom.StatusCount;
import com.my.blog.myblog.entity.custom.TimeCount;
import com.my.blog.myblog.service.BlogService;
import com.my.blog.myblog.service.BlogTypeService;
import com.my.blog.utils.ConstantUtil;
import com.my.blog.utils.ResultBean;
import com.my.blog.utils.SubStringUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.*;

/***
 *
 * @Auther: MuYun
 * @Date: 2021/9/2 16:38
 * @Description： 后台博客的controller
 *
 */
@RestController
@RequestMapping("/admin")
public class AdminBlogController {

    private Logger logger= LoggerFactory.getLogger(this.getClass());

    @Resource
    private BlogService blogService;

    @Resource
    private BlogTypeService blogTypeService;

    //上传封面图片到upload文件夹
    @PostMapping("/uploadBg")
    @SystemLog(description = ConstantUtil.UPLOAD_IMAGES,userType = ConstantUtil.USERTYPE_ADMIN)
    public Map<String,Object> uploadBgImages(HttpServletRequest request){
        //文件解析器
        CommonsMultipartResolver multipartResolver=
                new CommonsMultipartResolver(request.getSession().getServletContext());
        Map<String,Object> map=new HashMap<>();
        //判断请求是否携带文件
        if(multipartResolver.isMultipart(request)){
            //携带文件，转换成文件request
            MultipartHttpServletRequest multipartHttpServletRequest = (MultipartHttpServletRequest) request;
            //System.out.println("看下文件的request+"+multipartHttpServletRequest);
            //获取文件名
            Iterator<String> fileNames = multipartHttpServletRequest.getFileNames();
            //System.out.println("看下文件名的迭代器："+ fileNames);
            while(fileNames.hasNext()){
                //System.out.println("进迭代器了.......");
                //根据文件名从request获取文件对象
                MultipartFile file = multipartHttpServletRequest.getFile(fileNames.next());
                if(ObjectUtil.isNotEmpty(file)){
                    String filename = file.getOriginalFilename();
                    //文件名去除两端多余空格后是否是空
                    if(StrUtil.isNotEmpty(filename.trim())){
                        String myfilename = file.getOriginalFilename();
                        //截取出文件基础名（例如chunwu01.jpg截取出chunwu01）
                        String fileBasename = myfilename.substring(0, myfilename.lastIndexOf("."));
                        //获取拓展名
                        String fileExtname = myfilename.substring(myfilename.lastIndexOf(".") + 1).toUpperCase();
                        SimpleDateFormat format=new SimpleDateFormat("yyyy-MM-dd");
                        String newfilename = format.format(new Date());
                        //用当前时间+随机数重新命名
                        newfilename=newfilename+new Random().nextInt(100000)+"."+fileExtname;
                        System.out.println("随机生成的新文件名："+newfilename);

                        //获取当前工程的上一级目录
                        String s = System.getProperty("user.dir");
                        //获取当前工程名
                        String contextPath = request.getContextPath();
                        //设置该文件实际磁盘位置
                        String filePath=s+"/"+contextPath+"/upload/"+newfilename;
                        File localfile=new File(filePath);
                        if(!localfile.exists()){
                            localfile.mkdirs();
                        }
                        try {
                            file.transferTo(localfile);
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                        //获取url映射的文件夹
                        String parent=
                                request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+"/upload/";
                        newfilename=parent+newfilename;
                        System.out.println("url映射的文件："+newfilename);
                        map.put("fileName",fileBasename);
                        map.put("url",newfilename);
                        map.put("status",ResultBean.SUCCESS);
                    }
                }
            }
        }

        return map;
    }

    //以上防止在图片在编辑器内拖拽引发第二次上传导致的提示错误，和上面的基本一致
    @PostMapping("/uploadBlogImages")
    @SystemLog(description = ConstantUtil.UPLOAD_IMAGES,userType = ConstantUtil.UPLOAD_IMAGES)
    public Map<String,Object> uploadBlogImages(HttpServletRequest request){
        //文件解析器
        CommonsMultipartResolver multipartResolver=
                new CommonsMultipartResolver(request.getSession().getServletContext());
        Map<String,Object> map=new HashMap<>();
        //判断请求是否携带文件
        if(multipartResolver.isMultipart(request)){
            //获取文件request
            MultipartHttpServletRequest multipartHttpServletRequest = multipartResolver.resolveMultipart(request);
            System.out.println("看下文件的request+"+multipartHttpServletRequest);
            //获取文件名
            Iterator<String> fileNames = multipartHttpServletRequest.getFileNames();
            System.out.println("看下文件名的迭代器："+ fileNames);
            if(fileNames.hasNext()){
                //根据文件名从request获取文件对象
                MultipartFile file = multipartHttpServletRequest.getFile(fileNames.next());
                if(ObjectUtil.isNotEmpty(file)){
                    String filename = file.getOriginalFilename();
                    //文件名去除两端多余空格后是否是空
                    if(StrUtil.isNotEmpty(filename.trim())){
                        String myfilename = file.getOriginalFilename();
                        //截取出文件基础名（例如chunwu01.jpg截取出chunwu01）
                        String fileBasename = myfilename.substring(0, myfilename.lastIndexOf("."));
                        //获取拓展名
                        String fileExtname = myfilename.substring(myfilename.lastIndexOf(".") + 1).toUpperCase();
                        SimpleDateFormat format=new SimpleDateFormat("yyyy-MM-dd");
                        String newfilename = format.format(new Date());
                        //用当前时间+随机数重新命名
                        newfilename=newfilename+new Random().nextInt(100000)+"."+fileExtname;
                        System.out.println("随机生成的新文件名："+newfilename);

                        //获取当前工程的上一级目录
                        String s = System.getProperty("user.dir");
                        //获取当前工程名
                        String contextPath = request.getContextPath();
                        //设置该文件实际磁盘位置
                        String filePath=s+"/"+contextPath+"/upload/"+newfilename;
                        File localfile=new File(filePath);
                        //路径文件夹不存在
                        if(!localfile.exists()){
                            //创建
                            localfile.mkdirs();
                        }
                        try {
                            //io开始上传
                            file.transferTo(localfile);
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                        //获取url映射的文件夹
                        String parent=
                                request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+"/upload/";
                        newfilename=parent+newfilename;
                        System.out.println("url映射的文件："+newfilename);
                        map.put("fileName",fileBasename);
                        map.put("url",newfilename);
                        map.put("uploaded",1);
                        map.put("status",ResultBean.SUCCESS);
                    }
                }
            }
        }

        return map;
    }

    //新增博客
    @PostMapping("/addBlog")
    @SystemLog(description = ConstantUtil.BLOG_ADD,userType = ConstantUtil.USERTYPE_ADMIN)
    public ResultBean<Object> addBlog(String param,Blog blog){
        ResultBean<Object> resultBean=new ResultBean<>();
        //logger.info("进入后端前，博客的修改时间字段值为：{}",blog.getUpdateTime());
        blog.setAddTime(LocalDateTime.now());
        if(blogService.save(blog)){
            resultBean.setCode(ResultBean.SUCCESS);
        }else {
            resultBean.setCode(ResultBean.FAIL);
        }
        return resultBean;
    }

    //查询博客类别集合
    @PostMapping("/selectBlogType")
    public ResultBean<List<Blogtype>> selectBlogType(@RequestParam(value = "data") String data){
        ResultBean<List<Blogtype>> resultBean=new ResultBean<>();
        if("all".equals(data)){
            List<Blogtype> blogtypeList = blogTypeService.list();
            if(blogtypeList.size()==0){
                resultBean.setCode(ResultBean.FAIL);
            }else {
                resultBean.setData(blogtypeList);
            }
        }
        return resultBean;
    }

    //修改博客
    @PostMapping("/updateBlog")
    @SystemLog(description = ConstantUtil.BLOG_UPDATE,userType = ConstantUtil.BLOG_UPDATE)
    public ResultBean<Object> updateBlog(String prarm,Blog blog){
        ResultBean<Object> resultBean=new ResultBean<>();
        /*if(ObjectUtil.isNotEmpty(blog.getKeyword())){
            //中文的分号转成英文分号
            blog.setKeyword(SubStringUtil.subKeyword(blog.getKeyword()));
        }*/
        if(blogService.updateById(blog)){
            resultBean.setCode(ResultBean.SUCCESS);
        }else {
            resultBean.setCode(ResultBean.FAIL);
        }
        return resultBean;
    }

    //分组查询博客列表+模糊查询
    @PostMapping("/selectGroupLikeBlogListByPage")
    public ResultBean<IPage<Blog>> selectGroupLikeBlogListByPage(Blog blog,
                                   @RequestParam(value = "page",defaultValue = "1")Integer page,
                                   @RequestParam(value = "pageSize",defaultValue = "10")Integer pageSize,
                                   @RequestParam(value = "sort",defaultValue = "addTime")String sort){
        System.out.println(blog);
        QueryWrapper<Blog> blogQueryWrapper = designWrapper(blog,sort);
        //不查内容
        blogQueryWrapper.select(Blog.class,i->!"content".equals(i.getColumn()));
        IPage<Blog> blogPage = blogService.page(new Page<>(page, pageSize), blogQueryWrapper);
        ResultBean<IPage<Blog>> resultBean=new ResultBean<>();
        System.out.println(blogPage.getRecords());
        if(ObjectUtil.isNotEmpty(blogPage.getRecords())){
            resultBean.setData(blogPage);
        }else {
            resultBean.setCode(ResultBean.FAIL);
            blogPage.setTotal(0);
            resultBean.setData(blogPage);
        }
        return resultBean;
    }

    //获取各状态下的博客总数
    @GetMapping("/selectBlogListByStatus")
    public ResultBean<List<StatusCount>> selectBlogListByStatus(){
        List<Blog> blogList = blogService.list();
        List<StatusCount> scList=new ArrayList<>();
        int i=0;
        int j=0;
        int k=0;
        for(Blog blog:blogList){
            if(blog.getStatus()==-1){
                i++;
            }
            if(blog.getStatus()==1){
                j++;
            }
            if(blog.getStatus()==2){
                k++;
            }
        }
        scList.add(new StatusCount(-1,i));
        scList.add(new StatusCount(1,j));
        scList.add(new StatusCount(2,k));
        System.out.println(scList);
        return new ResultBean<>(scList);
    }

    //查询某个时间段下发表的博客数
    @GetMapping("/selectBlogListByDate")
    public ResultBean<List<TimeCount>> selectBlogListByDate(@RequestParam(value = "startTime")String startTime,
                                                            @RequestParam(value = "endTime")String endTime,
                                                            @RequestParam(value = "status")String status){
        HashMap<String,Object> map=new HashMap<>();
        if(StrUtil.isNotEmpty(startTime)){
            map.put("startTime",startTime);
        }
        if(StrUtil.isNotEmpty(endTime)){
            map.put("endTime",endTime);
        }
        if(StrUtil.isNotEmpty(status)){
            map.put("status",status);
        }
        List<TimeCount> timeCounts = blogService.selectBlogConutByDate(map);
        ResultBean<List<TimeCount>> resultBean=new ResultBean<>();
        if(timeCounts.size()!=0){
            resultBean.setCode(ResultBean.SUCCESS);
            resultBean.setData(timeCounts);
        }else {
            resultBean.setCode(ResultBean.FAIL);
        }
        return resultBean;
    }

    //根据点击量查询博客
    @GetMapping("/selectBlogByClick")
    public ResultBean<List<Blog>> selectBlogListByClick(){
        QueryWrapper<Blog> blogQueryWrapper=new QueryWrapper<>();
        blogQueryWrapper.lambda().orderByDesc(Blog::getClickNum);
        blogQueryWrapper.lambda().select(Blog::getId,Blog::getClickNum,Blog::getIntroduction);
        //只查七条
        Page<Blog> blogPage = blogService.page(new Page<>(1, 7), blogQueryWrapper);
        ResultBean<List<Blog>> resultBean=new ResultBean<>();
        if(blogPage.getRecords()==null){
            System.out.println(blogPage.getRecords());
            resultBean.setCode(ResultBean.FAIL);
        }else {
            resultBean.setData(blogPage.getRecords());
        }
        return resultBean;
    }

    //根据id查询博客
    @PostMapping("/selectBlogById")
    public ResultBean<Blog> selectBlogById(@RequestParam(value = "id") Integer id){
        //System.out.println("进来了0.0");
        QueryWrapper<Blog> blogQueryWrapper=new QueryWrapper<>();
        Blog blog = blogService.getOne(blogQueryWrapper.lambda().eq(Blog::getId, id));
        ResultBean<Blog> resultBean=new ResultBean<>();
        if(ObjectUtil.isNotEmpty(blog)){
            for(Blogtype blogtype:getType()){
                if(blog.getTypeId().equals(blogtype.getId().toString())){
                    blog.setTypeId(blog.getTypeId()+"="+blogtype.getTypeName());
                }
            }
            resultBean.setData(blog);
            //System.out.println(blog);
        }else {
            resultBean.setCode(ResultBean.FAIL);
            resultBean.setMsg("未查询到该博客，可能已被删除");
        }
        return resultBean;
    }



    /**
     *一些工具方法
     */

    //获取所有类别信息
    public List<Blogtype> getType() {
        return blogTypeService.list();

    }

    /**
     * 制造QueryWrapper的工具方法
     * @param blog
     * @param sort
     * @return
     */
    public static QueryWrapper<Blog> designWrapper(Blog blog,String sort){
        QueryWrapper<Blog> wrapper=new QueryWrapper<>();
        //简介
        if(StrUtil.isNotBlank(blog.getIntroduction())){
            wrapper.lambda().like(Blog::getIntroduction,blog.getIntroduction());
        }
        //标题
        if(StrUtil.isNotBlank(blog.getTitle())){
            wrapper.lambda().like(Blog::getTitle,blog.getTitle());
        }
        //关键词
        if(StrUtil.isNotBlank(blog.getKeyword())){
            wrapper.lambda().like(Blog::getKeyword,blog.getKeyword());
        }
        //是否置顶
        if(blog.getIsTop()!=null){
            wrapper.lambda().eq(Blog::getIsTop,blog.getIsTop());
        }
        //是否推荐（加精）
        if(blog.getIsRecommend()!=null){
            wrapper.lambda().eq(Blog::getIsRecommend,blog.getIsRecommend());
        }
        //新增（入库）时间
        if(blog.getAddTime()!=null){
            wrapper.lambda().eq(Blog::getAddTime,blog.getAddTime());
        }
        //博客状态
        if(blog.getStatus()!=null){
            wrapper.lambda().eq(Blog::getStatus,blog.getStatus());
        }
        //博客类别id
        if(blog.getTypeId()!=null){
            wrapper.lambda().eq(Blog::getTypeId,blog.getTypeId());
        }

        //设置排序字段
        switch (sort){
            case "addTime":
                wrapper.lambda().orderByDesc(Blog::getAddTime);
                break;
            case "updateTime":
                wrapper.lambda().orderByDesc(Blog::getUpdateTime);
                break;
        }

        return wrapper;
    }
}
